package com.shkco.xbjcc.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.shkco.exception.GlobalExceptionCode;
import com.shkco.result.JSONResult;
import com.shkco.utils.AssertUtil;
import com.shkco.xbjcc.doc.CourseDoc;
import com.shkco.xbjcc.domain.*;
import com.shkco.xbjcc.dto.CourseDto;
import com.shkco.xbjcc.dto.CourseOnLineSendMessageDto;
import com.shkco.xbjcc.dto.UserSendMessageDto;
import com.shkco.xbjcc.feign.MediaFileService;
import com.shkco.xbjcc.feign.SearchService;
import com.shkco.xbjcc.mapper.CourseMapper;
import com.shkco.xbjcc.mapper.CourseTypeMapper;
import com.shkco.xbjcc.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.shkco.xbjcc.vo.CourseDetailVo;
import com.shkco.xbjcc.vo.CourseInfoVo;
import com.shkco.xbjcc.vo.CourseOrderVo;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author whale
 * @since 2022-10-04
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private ITeacherService teacherService;

    @Autowired
    private ICourseDetailService courseDetailService;

    @Autowired
    private ICourseMarketService courseMarketService;

    @Autowired
    private ICourseResourceService courseResourceService;

    @Autowired
    private ICourseSummaryService courseSummaryService;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private CourseTypeMapper courseTypeMapper;

    @Autowired
    private SearchService searchService;

    @Autowired
    private ICourseCollectService courseCollectService;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private ICourseChapterService courseChapterService;

    @Autowired
    private MediaFileService mediaFileService;

    @Override
    public void save(CourseDto courseDto) {
        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseResource courseResource = courseDto.getCourseResource();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        List<Long> teacherIds = courseDto.getTeacherIds();

        Course course1 = selectByName(course.getName());
        AssertUtil.isNull(course1, GlobalExceptionCode.COURSE_EXISTING);
        Long courseId = saveCourse(course,teacherIds);

        courseDetail.setId(courseId);
        courseDetailService.insert(courseDetail);

        courseMarket.setId(courseId);
        courseMarketService.insert(courseMarket);

        courseResource.setCourseId(courseId);
        courseResourceService.insert(courseResource);

        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummaryService.insert(courseSummary);

        courseMapper.insertCourseTeacher(courseId,teacherIds);
        courseTypeMapper.updateTotalCountById(course.getCourseTypeId());
    }

    @Override
    public void onLineCourse(Long id) {
        // 根据id获取到课程信息
        Course course = selectById(id);
        AssertUtil.isNotNull(course,GlobalExceptionCode.COURSE_NO_EXISTING);
        // 修改课程状态,上架时间
        course.setStatus(Course.STATUS_ON_LINE);
        course.setOnlineTime(new Date());
        updateById(course);

        // 获取当前课程相关的信息
        CourseMarket courseMarket = courseMarketService.selectById(id);
        CourseSummary courseSummary = courseSummaryService.selectById(id);
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());

        CourseDoc courseDoc = new CourseDoc();
        BeanUtils.copyProperties(course,courseDoc);
        BeanUtils.copyProperties(courseMarket,courseDoc);
        BeanUtils.copyProperties(courseSummary,courseDoc);
        courseDoc.setCourseTypeName(courseType.getName());
        String charge = courseMarket.getCharge() == 1 ? "免费" : "付费";
        courseDoc.setCharge(charge);

        JSONResult jsonResult = searchService.saveSearch(courseDoc);
        AssertUtil.isTrue(jsonResult.isSuccess(),GlobalExceptionCode.COURSE_RELEASE_FAILURE);

        // 上线课程给收藏当前课程类型的用户发送消息
        Wrapper<CourseCollect> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id",id);
        List<CourseCollect> courseCollects = courseCollectService.selectList(wrapper);
        UserSendMessageDto userSendMessageDto = new UserSendMessageDto();
        for (CourseCollect courseCollect : courseCollects) {
            userSendMessageDto.setUserId(courseCollect.getUserId());
            userSendMessageDto.setContact(courseCollect.getContact());
        }
        CourseOnLineSendMessageDto courseOnLineSendMessageDto = new CourseOnLineSendMessageDto("课程发布",
                "亲爱的用户您好，最新课程 <a href='localhost:6002/list.html?courseId=" + courseDoc.getId() + "'> 测试 </a> 发布啦，点击课程了解详情"
                , Arrays.asList(userSendMessageDto));

        rocketMQTemplate.sendOneWay("course-message-topic:sms-tag", JSON.toJSONString(courseOnLineSendMessageDto));
    }

    @Override
    public void offLineCourse(Long id) {
        Course course = selectById(id);
        AssertUtil.isNotNull(course,GlobalExceptionCode.COURSE_NO_EXISTING);
        // 修改课程状态,下架
        course.setStatus(Course.STATUS_OFF_LINE);
        updateById(course);
        JSONResult jsonResult = searchService.delSearch(id);
        AssertUtil.isTrue(jsonResult.isSuccess(),GlobalExceptionCode.COURSE_SHELVES_FAILURE);
    }

    @Override
    public CourseDetailVo getDetail(Long courseId) {
        Course course = selectById(courseId);
        AssertUtil.isNotNull(course,GlobalExceptionCode.COURSE_NO_EXISTING);
        boolean boo = course.getStatus() == Course.STATUS_ON_LINE;
        AssertUtil.isTrue(boo,GlobalExceptionCode.COURSE_NO_EXISTING);
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        CourseSummary courseSummary = courseSummaryService.selectById(courseId);
        CourseDetail courseDetail = courseDetailService.selectById(courseId);
        List<Teacher> teachers = courseMapper.selectTeacherByCourseId(courseId);
        Wrapper<CourseChapter> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id",courseId);
        List<CourseChapter> courseChapters = courseChapterService.selectList(wrapper);
        Map<Long, CourseChapter> collect = courseChapters.stream().collect(Collectors.toMap(CourseChapter::getId, courseChapter -> courseChapter));
        JSONResult jsonResult = mediaFileService.getMediaByCourseId(courseId);
        AssertUtil.isTrue(jsonResult.isSuccess(),GlobalExceptionCode.COURSE_ACQUIRE_FAILURE);
        Object data = jsonResult.getData();
        AssertUtil.isNotNull(data,GlobalExceptionCode.ERROR);
        String jsonString = JSON.toJSONString(data);
        List<MediaFile> mediaFiles = JSON.parseArray(jsonString, MediaFile.class);
        mediaFiles.forEach(m->{
            m.setFileUrl("");
            CourseChapter courseChapter = collect.get(m.getChapterId());
            if (courseChapter != null){
                courseChapter.getMediaFiles().add(m);
            }
        });
        return new CourseDetailVo(course,courseMarket,courseChapters,teachers,courseDetail,courseSummary);
    }

    @Override
    public CourseInfoVo info(String courseIds) {
        // 分割courseIds
        Set<Long> collect = Arrays.stream(courseIds.split(","))
                // id必须为0-9的数字
                .filter(id -> id.matches("^[0-9]*$"))
                // 将分割后的id转为Long类型
                .map(id -> Long.valueOf(id))
                // 转为Set数组去重
                .collect(Collectors.toSet());
        boolean boo = collect.size() == courseIds.split(",").length;
        AssertUtil.isTrue(boo, GlobalExceptionCode.ERROR);
        List<Long> courseIdsList = collect.stream().collect(Collectors.toList());
        // 根据id查询课程信息
        List<Course> courses = selectBatchIds(courseIdsList);
        AssertUtil.isNotNull(courses, GlobalExceptionCode.ERROR);
        Map<Long, CourseMarket> courseMarketMap = courseMarketService.selectBatchIds(courseIdsList).stream().collect(Collectors.toMap(CourseMarket::getId, courseMarket -> courseMarket));
        CourseInfoVo courseInfoVo = new CourseInfoVo();
        List<CourseOrderVo> courseOrderVos = new ArrayList<>();
        courses.forEach(course ->{
            CourseOrderVo courseOrderVo = new CourseOrderVo();
            boolean isOK = Course.STATUS_ON_LINE == course.getStatus();
            AssertUtil.isTrue(isOK, GlobalExceptionCode.ERROR);
            CourseMarket courseMarket = courseMarketMap.get(course.getId());
            AssertUtil.isNotNull(courseMarket, GlobalExceptionCode.ERROR);
            courseOrderVo.setCourse(course);
            courseOrderVo.setCourseMarket(courseMarket);
            courseInfoVo.setTotalAmount(courseInfoVo.getTotalAmount().add(courseMarket.getPrice()));
            courseOrderVos.add(courseOrderVo);
        });
        courseInfoVo.setCourseInfos(courseOrderVos);
        return courseInfoVo;
    }

    private Long saveCourse(Course course, List<Long> teacharIds) {
        course.setStatus(Course.STATUS_OFF_LINE);
        course.setLoginId(40L);
        course.setLoginUserName("17666666666");
        String teacherNames = teacherService.selectBatchIds(teacharIds).stream().map(teacher -> teacher.getName()).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        insert(course);
        return course.getId();
    }


    private Course selectByName(String name) {
        Wrapper<Course> wrapper = new EntityWrapper<>();
        wrapper.eq("name",name);
        return selectOne(wrapper);
    }
}
